<template>
	<div class="maskCenter">
		<div id="box" :class="[visible ? 'systemDialog' : 'systemDialog-hide', fullScreen ? 'fullScreen' : '']">
			<div class="dialog-header" v-movew @dblclick="headerDbclick">
				<span>{{ title }}</span>
				<div class="icon-wrapper">
					<el-tooltip class="item" effect="dark" content="关闭" placement="top-start">
						<span class="icon iconfont iconbiaoqianlan-guanbi close" @click="hide"></span>
					</el-tooltip>
				</div>
			</div>
			<div class="dialog-body" @contextmenu.prevent>
				<el-tabs v-model="activeName" @tab-click="tabClick">
					<el-tab-pane label="流程图" name="first">
						<div id="viewDiagramDivF"></div>
						<ul class="rightcli" id="rightcli" ref="menu" :class="{ rightcliClose: flag == 0, rightcliOpen: flag == 1 }">
							<li @click="flowsend" class="litem"><span class="drop-menu-item-icon iconliucheng-fasong"></span>流转</li>
							<li @click="flowback" class="litem" v-if="canBack"><span class="drop-menu-item-icon iconliucheng-huitui"></span>回退</li>
						</ul>
					</el-tab-pane>
					<el-tab-pane label="日志" name="second">
						<flowLog :wfInstId="wfInstId" v-if="activeName == 'second'"></flowLog>
					</el-tab-pane>
				</el-tabs>
			</div>
			<flowSend v-if="showFlowSend" @close="closeFlowSend" @ok="FlowSendsave" :instNodeId="instNodeId" :sendtype="sendtype" :deptId="deptId"></flowSend>
			<cellView
				v-if="showCell && view == 'cellView.vue'"
				:nodeId="nodeId"
				:tinstNodeId="instNodeId"
				:wpId="wpId"
				:tworkId="tworkId"
				@close="closeCell"
				:tdeptId="deptId"
				:acceptTime="acceptTime"
				:businessInfo="wfVar"
			></cellView>
		</div>
	</div>
</template>

<script>
	import movew from '@/directives/winmove'
	import flowLog from './flowLog.vue'
	import flowSend from '@/system/components/flowSend.vue'

	import { wfimage } from '@/system/api/flowSend'
	import { deepCopy } from '@/utils/public'
	import go from 'gojs'
	import log from '@/system/pages/log'
	import { fun } from '../pages/customPage/generator/config'

	let gmake = go.GraphObject.make
	export default {
		directives: { movew },
		name: 'winFlowView',
		props: {
			wfInstId: { default: null },
			instNodeId: { default: null },
			wfInstUserId: { default: null }, //消息ID
			finish: { default: false }, //状态
			acceptTime: { default: null }, //接受时间
		},
		data() {
			return {
				wfVar: null,
				deptId: null,
				visible: true,
				info: {},
				myDiagram: null,
				lightText: 'whitesmoke',
				model: {
					class: 'GraphLinksModel',
					linkFromPortIdProperty: 'fromPort',
					linkToPortIdProperty: 'toPort',
					nodeDataArray: [],
					linkDataArray: [],
				},
				od: true,
				actvieNode: null, //gojs 中 当前  可用的节点
				activeName: 'first',
				flag: -1, //流程节点右键
				canBack: true,
				showFlowSend: false,
				sendtype: null,
				node: [],
				edge: [],
				bkcolor: ['#5cadff', '#19be6b', '#5E77FF'],
				lkcolor: ['#666'],
				showCell: false,
				wpId: null,
				tworkId: null,
				view: null,
				nodeId: 1,
				title: '流程图',
				timer: null,
				fullScreen: true,
			}
		},
		components: {
			flowLog,
			flowSend,
		},
		mounted() {
			let self = this

			this.myDiagram = gmake(
				go.Diagram,
				'viewDiagramDivF', // 网格锁定must name or refer to the DIV HTML element
				{
					initialContentAlignment: go.Spot.Center,
					allowDrop: true, // must be true to accept drops from the Palette
					scrollsPageOnFocus: false,
					'undoManager.isEnabled': true, // enable undo & redo
					allowRelink: true,
					padding: 0,
					isReadOnly: true,
					'draggingTool.isGridSnapEnabled': true, //自动锁定
					nodeSelectionAdornmentTemplate: gmake(
						go.Adornment,
						'Auto',
						gmake(go.Shape, 'Rectangle', {
							fill: 'white',
							stroke: null,
						})
					),
					doubleClick: function(e) {
						console.log(e)
					},
				}
			)

			function showContextMenu(obj, diagram, tool) {
				if (obj.data.enable) {
					if (obj.data.nodestate == 0) {
						self.canBack = false
						self.$refs.menu.style.setProperty('--height', 50 + 'px')
					} else {
						self.canBack = true
						self.$refs.menu.style.setProperty('--height', 80 + 'px')
					}
					let mousePt = diagram.lastInput.viewPoint
					self.$refs.menu.style.left = mousePt.x + 'px'
					self.$refs.menu.style.top = mousePt.y + 'px'
					self.flag = 1
				} else {
					self.flag = -1
				}
			}

			function hideContextMenu() {
				if (self.flag == 1) {
					self.flag = 0
				}
			}

			var myContextMenu = gmake(go.HTMLInfo, {
				//右键菜单
				show: showContextMenu,
				hide: hideContextMenu,
			})

			this.myDiagram.nodeTemplateMap.add(
				'all', //流程
				gmake(
					go.Node,
					'Spot',
					self.nodeStyle(),
					{
						contextMenu: myContextMenu,
						resizable: true,
						resizeObjectName: 'PANEL',
						doubleClick: function(e, node) {
							console.log(self.node)
							if (node.data.enable) {
								// console.log(self.tworkId);
								// console.log(self.wpId);
								// console.log(self.nodeId);
								let flge = self.node.find(item => item.state == 0)
								if (flge && flge.repId) {
									self.wpId = flge.repId
								}
								self.showCell = true
							}
						},
						//	            isShadowed: true,//加阴影
					},
					gmake(
						go.Panel,
						'Auto',
						gmake(
							go.Shape,
							'RoundedRectangle',
							{
								fill: 'rgba(83, 168, 255, 1)',
								stroke: '#09d3ac',
								strokeWidth: 0,
								name: 'nodeshape',
								minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
							},
							new go.Binding('fill', 'bkcolor').makeTwoWay()
						),
						gmake(
							go.TextBlock,
							{
								font: 'bold 12px Helvetica, Arial, sans-serif',
								stroke: this.lightText, //stroke  字体
								wrap: go.TextBlock.WrapFit,
								textAlign: 'center',
								editable: false,
								name: 'nodetext',
							},
							new go.Binding('text').makeTwoWay(),

							new go.Binding('nodestate').makeTwoWay()
						)
					),
					new go.Binding('width').makeTwoWay(),
					new go.Binding('height').makeTwoWay(),
					// three named ports, one on each side except the top, all output only:
					this.makePort('T', go.Spot.Top, true, true),
					this.makePort('L', go.Spot.Left, true, true),
					this.makePort('R', go.Spot.Right, true, true),
					this.makePort('B', go.Spot.Bottom, true, true)
				)
			)

			this.myDiagram.nodeTemplateMap.add(
				'Start', //开始
				gmake(
					go.Node,
					'Spot',
					self.nodeStyle(),
					{
						contextMenu: myContextMenu,
						resizable: true,
						resizeObjectName: 'PANEL',
						doubleClick: function(e, node) {
							if (node.data.enable) {
								self.showCell = true
							}
						},
						//	            isShadowed: true,//加阴影
					},
					gmake(
						go.Panel,
						'Auto',
						gmake(
							go.Shape,
							'Ellipse',
							{
								//	                minSize: new go.Size(35, 35),
								fill: 'rgba(83, 168, 255, 1)',
								stroke: '#00A9C9',
								strokeWidth: 0,
								name: 'nodeshape',
								minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
							},
							new go.Binding('fill', 'bkcolor').makeTwoWay(),
							new go.Binding('figure', 'figure')
						),
						gmake(
							go.TextBlock,
							'Start',
							{
								font: 'bold 12px Helvetica, Arial, sans-serif',
								stroke: this.lightText,
								textAlign: 'center',
								name: 'nodetext',
							},
							new go.Binding('text').makeTwoWay(),
							new go.Binding('nodestate').makeTwoWay()
						)
					),
					new go.Binding('width').makeTwoWay(),
					new go.Binding('height').makeTwoWay(),
					this.makePort('T', go.Spot.Top, true, false),
					this.makePort('L', go.Spot.Left, true, false),
					this.makePort('R', go.Spot.Right, true, false),
					this.makePort('B', go.Spot.Bottom, true, false)
				)
			)

			self.myDiagram.nodeTemplateMap.add(
				'End',
				gmake(
					go.Node,
					'Spot',
					this.nodeStyle(),
					{
						resizable: true,
						resizeObjectName: 'PANEL',
						//	            isShadowed: true,//加阴影
						doubleClick: function(e, node) {
							console.log(node)
						},
					},
					gmake(
						go.Panel,
						'Auto',
						gmake(
							go.Shape,
							'Ellipse',
							{
								//	              minSize: new go.Size(35, 35),
								fill: 'rgba(83, 168, 255, 1)',
								stroke: '#009688',
								strokeWidth: 0,
								name: 'nodeshape',
								minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
							},
							new go.Binding('fill', 'bkcolor').makeTwoWay()
						),
						gmake(
							go.TextBlock,
							'End',
							{
								font: 'bold 12px Helvetica, Arial, sans-serif',
								stroke: this.lightText,
								textAlign: 'center',
								name: 'nodetext',
							},
							new go.Binding('text').makeTwoWay(),
							new go.Binding('nodestate').makeTwoWay()
						)
					),
					new go.Binding('width').makeTwoWay(),
					new go.Binding('height').makeTwoWay(),
					this.makePort('T', go.Spot.Top, false, true),
					this.makePort('L', go.Spot.Left, false, true),
					this.makePort('R', go.Spot.Right, false, true),
					this.makePort('B', go.Spot.Bottom, false, true)
				)
			)
			//	      self.myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
			//	      self.myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal; //线的转弯
			self.myDiagram.nodeTemplateMap.add(
				'textblo',
				gmake(
					go.Node,
					'Auto',
					self.nodeStyle(),
					{
						resizable: true,
						resizeObjectName: 'PANEL',
						text: 'node',
						doubleClick: function(e, node) {
							console.log(node)
						},
						//	            isShadowed: true,//加阴影
					},
					gmake(
						go.Panel,
						'Auto',
						gmake(
							go.Shape,
							{
								fill: 'rgba(83, 168, 255, 1)',
								stroke: '#607d8b',
								strokeWidth: 0,
								name: 'nodeshape',
								minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
							},
							new go.Binding('fill', 'bkcolor').makeTwoWay(),
							new go.Binding('text').makeTwoWay()
						),
						gmake(
							go.TextBlock,
							{
								margin: 5,
								wrap: 30,
								textAlign: 'center',
								editable: true,
								font: 'Arial',
								stroke: '#ffffff',
								name: 'nodetext',
							},
							new go.Binding('text').makeTwoWay(),
							new go.Binding('nodestate').makeTwoWay()
						),
						new go.Binding('text').makeTwoWay()
					)
				)
			)

			self.myDiagram.nodeTemplateMap.add(
				'Comment',
				gmake(
					go.Node,
					'Spot',
					self.nodeStyle(),
					{
						resizable: true,
						resizeObjectName: 'PANEL',
						click: function(e, node) {
							console.log(node)
						},
						doubleClick: function(e, node) {
							console.log(node)
						},
						//	            isShadowed: true,//加阴影
					},
					gmake(
						go.Panel,
						'Auto',
						gmake(
							go.Shape,
							'Diamond',
							{
								//	              minSize: new go.Size(60, 30),
								fill: 'rgba(83, 168, 255, 1)',
								stroke: null,
								strokeWidth: 0,
								name: 'nodeshape',
								minSize: new go.Size(60, 30), //设置了大小，那么手动调节的地方也要设置
							},
							new go.Binding('fill', 'bkcolor').makeTwoWay()
						),
						gmake(
							go.TextBlock,
							'???',
							{
								wrap: go.TextBlock.WrapFit,
								textAlign: 'center',
								font: 'bold 12px Helvetica, Arial, sans-serif',
								stroke: '#fff',
								name: 'nodetext',
							},
							new go.Binding('text').makeTwoWay(),
							new go.Binding('nodestate').makeTwoWay()
						)
					),
					new go.Binding('width').makeTwoWay(),
					new go.Binding('height').makeTwoWay(),
					this.makePort('T', go.Spot.Top, true, true),
					this.makePort('L', go.Spot.Left, true, true),
					this.makePort('R', go.Spot.Right, true, true),
					this.makePort('B', go.Spot.Bottom, true, true)
				)
			)

			self.myDiagram.linkTemplate = gmake(
				go.Link, // the whole link panel
				{
					routing: go.Link.AvoidsNodes,
					selectionAdorned: true,
					mouseEnter: function(e, link) {
						link.findObject('HIGHLIGHT').stroke = 'rgba(30,144,255,0.2)'
					},
					mouseLeave: function(e, link) {
						link.findObject('HIGHLIGHT').stroke = 'transparent'
					},
					doubleClick: function(e, link) {
						console.log(link)
					},
				},
				new go.Binding('points').makeTwoWay(),
				gmake(
					go.Shape, // the highlight shape, normally transparent
					{
						isPanelMain: true,
						strokeWidth: 8,
						stroke: 'transparent',
						name: 'HIGHLIGHT',
					}
				),
				gmake(
					go.Shape, // the link path shape
					{
						isPanelMain: true,
						stroke: 'gray',
						strokeWidth: 2,
					},
					new go.Binding('stroke', 'lkcolor').makeTwoWay(),
					new go.Binding('fill', 'lkcolor').makeTwoWay()
				),
				gmake(
					go.Shape, // the arrowhead
					{
						toArrow: 'standard',
						stroke: 'gray',
						fill: 'gray',
					},
					new go.Binding('stroke', 'lkcolor').makeTwoWay(),
					new go.Binding('fill', 'lkcolor').makeTwoWay()
				),
				gmake(
					go.Panel,
					'Auto', // the link label, normally not visible
					{
						visible: true,
					},
					new go.Binding('visible', 'visible').makeTwoWay(),
					gmake(
						go.Shape,
						'RoundedRectangle', // the label shape
						{
							fill: 'transparent',
							stroke: null,
						}
					),
					gmake(
						go.TextBlock,
						' ', // the label
						{
							textAlign: 'center',
							font: '10pt helvetica, arial, sans-serif',
							stroke: '#999',
							editable: false,
						},
						new go.Binding('text').makeTwoWay(),
						new go.Binding('name').makeTwoWay()
					)
				)
			) //线上文字

			this.wfimage()
		},
		methods: {
			// 全屏
			headerDbclick() {
				this.fullScreen = !this.fullScreen
			},
			tabClick(tab, e) {
				if (this.activeName == 'first') {
					this.flag = -1
				}
			},
			hide() {
				this.visible = false
				setTimeout(() => {
					this.$emit('close', false)
				}, 400)
			},
			nodeStyle(e, obj) {
				let _this = this
				return [
					new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
					{
						locationSpot: go.Spot.Center,
						mouseEnter: function(e, obj) {
							_this.showPorts(obj.part, true)
						},
						mouseLeave: function(e, obj) {
							_this.showPorts(obj.part, false)
						},
					},
				]
			},
			showPorts(node, show) {
				var diagram = node.diagram
				if (!diagram || diagram.isReadOnly || !diagram.allowLink) return
				node.ports.each(function(port) {
					port.stroke = show ? 'white' : null
				})
			},
			//当鼠标选中的时候出现可以连线的点，一般有上下左右四个点
			makePort(name, spot, output, input) {
				//不能用demo4的  makePort  要不然边框会缺失
				// the port is basically just a small circle that has a white stroke when it is made visible
				return go.GraphObject.make(go.Shape, 'Circle', {
					fill: 'transparent',
					stroke: null, // this is changed to "white" in the showPorts function
					desiredSize: new go.Size(8, 8),
					name: name + 'circle',
					alignment: spot,
					alignmentFocus: spot, // align the port on the main Shape
					portId: name, // declare this object to be a "port"
					fromSpot: spot,
					toSpot: spot, // declare where links may connect at this port
					fromLinkable: output,
					toLinkable: input, // declare whether the user may draw links to/from here
					cursor: 'pointer', // show a different cursor to indicate potential link point
				})
			},
			setNode(tnode) {
				this.node.forEach((node, index) => {
					if (node.wfNodeCode == tnode.key) {
						this.myDiagram.model.setDataProperty(tnode, 'bkcolor', this.bkcolor[node.state])
						if (node.state == 0 && node.wfInstNodeId == this.instNodeId) {
							//设置节点状态
							this.myDiagram.model.setDataProperty(tnode, 'enable', true)
							this.actvieNode = tnode
							this.timer = setInterval(this.setActiveNode, 800)
						}
					}
				})
			},
			setLink(tedge) {
				this.edge.forEach((edge, index) => {
					if (edge.wfEdgeCode == tedge.key) {
						this.myDiagram.model.setDataProperty(tedge, 'lkcolor', this.lkcolor[0])
					}
				})
			},
			initNode() {
				//遍历
				this.myDiagram.model.nodeDataArray.forEach((node, index) => {
					this.myDiagram.model.setDataProperty(node, 'enable', false)
					this.myDiagram.model.setDataProperty(node, 'bkcolor', '#c5c8ce')
					this.setNode(node)
				})
				this.myDiagram.model.linkDataArray.forEach((link, index) => {
					this.myDiagram.model.setDataProperty(link, 'lkcolor', '#c5c8ce')
					this.setLink(link)
				})
			},
			wfimage() {
				//根据流程实例id  获取流程信息并用gojs  展现  然后初始化节点   打开流程图
				let param = {
					wfInstUserId: this.wfInstUserId,
					wfInstId: this.wfInstId,
					finish: this.finish,
				}
				wfimage(param).then(res => {
					if (res.success) {
						this.deptId = res.info.deptId
						this.myDiagram.model = go.Model.fromJson(res.info.pic)
						this.node = res.info.node
						this.edge = res.info.edge
						let varObj = {}
						this.wpId = res.info.repId
						res.info.var.forEach(tvar => {
							varObj[tvar.name] = tvar.value
							if (tvar.name == 'view') {
								if (tvar.value == null) {
									this.message('流程发送的时候必须给view赋值！', 3)
								}
								this.view = tvar.value
							}

							// if (tvar.name == "wpId") {
							//   this.wpId = tvar.value;
							// }
							//							console.log(this.wpId);
						})

						this.wfVar = varObj

						if (res.info.wfName) {
							this.title = res.info.wfName
						}
						this.tworkId = res.info.workId //获取具体数据id
						//wpId:null,	tworkId:   就是dataId,
						this.initNode()
					}
				})
			},
			setActiveNode() {
				//设置闪动节点
				if (this.actvieNode) {
					if (this.od) {
						this.myDiagram.model.setDataProperty(this.actvieNode, 'bkcolor', 'rgba(92, 173, 255,0.85)')
					} else {
						this.myDiagram.model.setDataProperty(this.actvieNode, 'bkcolor', '#5cadff')
					}
					this.od = !this.od
				}
			},
			flowsend() {
				//流程发送
				this.flag = 0
				//				this.instNodeId=7;
				this.sendtype = 1
				this.showFlowSend = true
			},
			flowback() {
				//流程回退
				this.flag = 0
				//				this.instNodeId=7;
				this.sendtype = -1
				this.showFlowSend = true
			},
			FlowSendsave(e) {
				//流程发送界面   点击发送后 关闭流程发送界面
				this.showFlowSend = false
				this.visible = false
				setTimeout(() => {
					this.$emit('close', true)
				}, 400)
			},
			closeFlowSend() {
				//关闭流程发送界面
				this.showFlowSend = false
			},
			closeCell(e) {
				//表单发送流程后的关闭  需要关闭流程展示界面   ， 如果是手动关闭表单，不用关闭流程界面
				this.showCell = false
				if (e) {
					setTimeout(() => {
						this.$emit('close', true)
					}, 400)
				}
			},
		},
		beforeDestroy() {
			if (this.timer) {
				clearInterval(this.timer)
			}
		},
	}
</script>

<style scoped>
	#box {
		height: 70%;
		width: 80%;
	}

	#box.fullScreen {
		position: fixed !important;
		top: 60px;
		left: 220px;
		height: calc(100% - 70px);
		width: calc(100% - 230px);
		background: rgba(255, 255, 255, 1);
	}

	#viewDiagramDivF {
		flex-grow: 1;
		background-color: var(--page-back-color);
		height: 100%;
		width: 100%;
		margin: 0 auto;
	}

	#viewDiagramDivF 
/* >>> */
::v-deep :focus {
		outline: none !important;
	}

	#viewDiagramDivF 
/* >>> */
::v-deep canvas {
		height: 100%;
	}

	#viewDiagramDivF 
/* >>> */
::v-deep div {
		height: 100%;
	}

	/*tabs 样式*/
	/* >>> */
	::v-deep .el-tabs__header {
		margin: 0px;
		margin-bottom: 16px;
	}

	.el-tabs {
		height: 100%;
	}

	/* >>> */
	::v-deep .el-tabs__active-bar {
		width: 80px !important;
	}

	/* >>> */
	.el-tabs--top .el-tabs__item.is-top:nth-child(2) {
		padding-left: 0px;
	}

	/* >>> */
	::v-deep .el-tabs__item {
		padding: 0 !important;
		font-weight: bold;
		letter-spacing: 2px;
		height: 26px;
		line-height: 26px;
		color: var(--disable-text-color);
		text-align: center;
		min-width: 80px;
	}

	/*活动颜色*/
	/* >>> */
	::v-deep .el-tabs__item.is-active {
		color: var(--active-color);
	}

	/*tabs 分割线*/
	/* >>> */
	::v-deep .el-tabs__nav-wrap::after {
		height: 1px;
		background-color: var(--page-hr-line-color);
	}

	/*tabs 前面没有标签内容要显示,去除margin-left*/
	.noLabel 
/* >>> */
::v-deep .el-form-item__content {
		margin-left: 0 !important;
	}

	/* >>> */
	::v-deep .el-tabs__content {
		height: calc(100% - 30px);
		padding-bottom: 20px;
	}

	/* >>> */
	::v-deep .el-tab-pane {
		height: 100%;
	}

	#rightcli {
		--height: 80px;
	}

	.rightcli {
		position: absolute;
		top: 0px;
		left: 0px;
		width: 100px;
		text-align: center;
		list-style: none;
		z-index: 99;
		background: var(--page-back-color);
		color: var(--page-lable-text-color);
		box-shadow: 0px 10px 20px 0px var(--drop-menu-boxshadow-color), 0px -10px 20px 0px var(--drop-menu-boxshadow-color);
		font-size: 14px;
		border-radius: 4px;
		height: 0;
		overflow: hidden;
	}

	.rightcli li {
		height: 30px;
		line-height: 30px;
		cursor: pointer;
		text-align: left;
		font-size: 14px;
		font-family: Microsoft YaHei;
		font-weight: 400;
	}

	.rightcli li:hover {
		background: var(--button-hover-back-color);
		color: var(--button-active-text-color);
		cursor: pointer;
	}

	.rightcli li:active {
		background: var(--button-active-back-color);
		color: var(--button-active-text-color);
		cursor: pointer;
	}

	.litem:first-child {
		margin-top: 10px;
	}

	.drop-menu-item-icon {
		color: var(--icon-color);
		font-family: 'iconfont';
		margin-left: 17px;
		font-size: 15px;
		margin-right: 10px;
	}

	.rightcliOpen {
		height: var(--height);
		animation: menuopen 0.3s;
	}

	@keyframes menuopen {
		from {
			height: 0;
		}
		to {
			height: var(--height);
		}
	}

	.rightcliClose {
		height: 0;
		animation: menuclose 0.3s;
	}

	@keyframes menuclose {
		from {
			height: var(--height);
		}
		to {
			height: 0;
		}
	}

	/*下拉框不可用*/
	.disable {
		background: var(--tag-button-disable-back-color);
	}
</style>
